home *** CD-ROM | disk | FTP | other *** search
- #include "global.h"
- #include "ctype.h"
- #include "commands.h"
- #include "mbuf.h"
- #include "netuser.h"
- #ifndef MSDOS
- #include "tcp.h"
- #include "usock.h"
- #endif
- #include "files.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: crontab.c,v 1.18 1997/08/19 01:19:22 root Exp root $";
- #endif
-
- #ifdef CRONTAB
-
- struct crontab {
- char minute[60];
- char hour[24];
- char day[31];
- char dayofweek[7];
- char month[12];
- char *cmd;
- struct crontab *next;
- };
- #define NULLCRONTAB ((struct crontab *)0)
-
- static struct crontab *CRON;
- static int CRONactive = -1;
-
- extern struct cmds Cmds[];
- extern const char *Days[7], *Months[12]; /*lint !e15 */
- #ifdef LOCK
- extern int Kblocked;
- #endif
-
-
- static void processcrontab (void);
- static void listsegment (char *field, int size, int offset);
- static void parsesegment (char *field, int size, char *val, int offset, char **tbl);
- static void addline (int argc, char *argv[]);
- static int docronload (int argc,char *argv[],void *p);
- static int docronlist (int argc,char *argv[],void *p);
- static int docronadd (int argc,char *argv[],void *p);
- static int docronclear (int argc,char *argv[],void *p);
- static int docrondel (int argc,char *argv[],void *p);
-
-
- /* crontab subcommand table */
- static struct cmds CRONtab[] = {
- { "add", docronadd, 0, 7, "cron add min hour day month dayofweek \"cmd\"" },
- { "clear", docronclear, 0, 0, NULLCHAR },
- { "delete", docrondel, 0, 2, "cron delete entry#" },
- { "list", docronlist, 0, 0, NULLCHAR },
- { "load", docronload, 0, 0, NULLCHAR },
- { NULLCHAR, NULL, 0, 0, NULLCHAR }
- };
-
-
- int
- docrontab (argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- return subcmd (CRONtab, argc, argv, p);
- }
-
-
- static int
- docronadd (argc, argv, p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- if (argc >= 7)
- addline (--argc, ++argv); /*lint !e608 */
- return 0;
- }
-
-
- static int
- docrondel (argc, argv, p)
- int argc OPTIONAL;
- char *argv[];
- void *p OPTIONAL;
- {
- struct crontab *cr, *tmp = NULLCRONTAB;
- int i;
- i = (atoi (argv[1]) - 1);
- if (!i) {
- cr = CRON;
- CRON = cr->next;
- free (cr->cmd);
- free (cr);
- } else {
- for (cr = CRON; cr; cr = tmp,i--) {
- if (i == 1) {
- tmp = cr->next;
- cr->next = tmp->next;
- free (tmp->cmd);
- free (tmp);
- break;
- }
- }
- }
- return 0;
- }
-
-
- static int
- docronclear (argc, argv, p)
- int argc OPTIONAL;
- char *argv[];
- void *p OPTIONAL;
- {
- struct crontab *cr, *tmp;
-
- for (cr = CRON; cr; cr = tmp) {
- tmp = cr->next;
- free (cr->cmd);
- free (cr);
- }
- CRON = NULLCRONTAB;
- if (argv)
- tprintf ("Crontab cleared!\n");
- return 0;
- }
-
-
- static int
- docronload (argc, argv, p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- FILE *fp;
- char const *filename = CRONTABFile;
- char buffer[1024 + 9], *cp;
-
- if (argc > 1) {
- filename = argv[1];
- } else {
- (void) docronclear (1, (char **)0, (void *)0);
- }
- if ((fp = fopen (filename, READ_TEXT)) != NULLFILE) {
- while (!feof(fp)) {
- strcpy (buffer, "cron add ");
- if (fgets (&buffer[9], 1024, fp)) {
- cp = skipwhite (&buffer[9]);
- if (*cp && *cp != '#')
- (void) cmdparse (Cmds, buffer, NULL);
- }
- }
- (void) fclose (fp);
- }
- if (argv)
- tprintf ("Crontab loaded!\n");
- return 0;
- }
-
-
- static int
- docronlist (argc, argv, p)
- int argc OPTIONAL;
- char *argv[] OPTIONAL;
- void *p OPTIONAL;
- {
- struct crontab *c;
- int i = 1;
-
- for (c = CRON; c; c = c->next) {
- tprintf ("%3d: ", i++);
- listsegment (c->minute, 60, 0);
- listsegment (c->hour, 24, 0);
- listsegment (c->day, 31, 1);
- listsegment (c->month, 12, 1);
- listsegment (c->dayofweek, 7, 0);
- tprintf ("\"%s\"\n", c->cmd);
- }
- return 0;
- }
-
-
- /* Start up cron server */
- int
- cron1 (argc, argv, p)
- int argc OPTIONAL;
- char *argv[] OPTIONAL;
- void *p OPTIONAL;
- {
- if (CRONactive != -1)
- return 0;
-
- (void) ksignal (Curproc, 0); /* Don't keep the parser waiting */
- chname (Curproc, "Cron server");
- CRONactive = Curproc->output;
- (void) docronload (1, (char **)0, (void *)0);
-
- server_disconnect_io ();
- while (CRONactive != -1) {
- (void) kpause (60000);
- processcrontab ();
- }
- return 0;
- }
-
-
-
- /* Shut down cron server */
- int
- cron0 (argc, argv, p)
- int argc OPTIONAL;
- char *argv[] OPTIONAL;
- void *p OPTIONAL;
- {
- return (deleteserver (&CRONactive));
- }
-
-
- static void
- listsegment (field, size, offset)
- char *field;
- int size, offset;
- {
- int i, k, usecomma = 0;
-
- /* special case check for '*' */
- for (i = 0; i < size; i++) {
- if (!field[i])
- break;
- }
- if (i == size)
- tputc ('*');
- else { /* otherwise, one or more (but not ALL) values */
- for (i = 0; i < size; i++) {
- /* Skip if this index is clear */
- if (!field[i])
- continue;
-
- /* We have at least ONE value here, so place a comma, if needed */
- if (usecomma)
- tputc (',');
- else
- usecomma = 1;
-
- if ((i + 1) == size || !field[i + 1])
- tprintf ("%-d", i + offset);
- else {
- for (k = i + 1; k < size; k++) {
- if (!field[k])
- break;
- }
- k--;
- tprintf ("%-d-%-d", i + offset, k + offset);
- i = k;
- }
- }
- }
- tputc (' ');
- }
-
-
- static void
- parsesegment (field, size, val, offset, tbl)
- char *field;
- int size;
- char *val;
- int offset;
- char **tbl;
- {
- char *cp = val, *temp, itwas;
- int val1, val2, i, stepval;
-
- while (cp && *cp) {
- itwas = 0;
- if ((temp = strpbrk (cp, "-,")) != NULLCHAR) {
- itwas = *temp;
- *temp++ = 0;
- }
- if (*cp == '*') {
- for (i = 0; i < size; i++)
- field[i] = 1;
- } else if (!isdigit (*cp)){
- for (i = 0; i < size; i++) {
- if (!stricmp (tbl[i], cp)) {
- field[i] = 1;
- break;
- }
- }
- } else {
- val1 = atoi (cp);
- if (offset)
- val1 -= offset;
- if (itwas == '-' && temp) {
- cp = temp;
- if ((temp = strpbrk (cp, ",/")) != NULLCHAR) {
- itwas = *temp;
- *temp++ = 0;
- }
- val2 = atoi (cp);
- if (!offset)
- val2++;
- if (itwas == '/' && temp) {
- cp = temp;
- if ((temp = strpbrk (cp, "-,")) != NULLCHAR)
- *temp++ = 0;
- stepval = atoi (cp);
- } else
- stepval = 1;
- for (i = val1; i < val2 && i < size; i += stepval)
- field[i] = 1;
- } else {
- field[val1] = 1;
- }
- }
- cp = temp;
- }
- }
-
-
- static void
- addline (argc, argv)
- int argc;
- char *argv[];
- {
- struct crontab *c;
- int i;
-
- c = (struct crontab *) callocw (1, sizeof (struct crontab));
- if (c != NULLCRONTAB) {
- parsesegment (c->minute, 60, argv[0], 0, (char **)0);
- parsesegment (c->hour, 24, argv[1], 0, (char **)0);
- parsesegment (c->day, 31, argv[2], 1, (char **)0);
- parsesegment (c->month, 12, argv[3], 1, (char **)Months);
- parsesegment (c->dayofweek, 7, argv[4], 0, (char **)Days);
- argc--;
- for (i = 5; i < argc; i++) {
- argv[i][strlen(argv[i])] = ' ';
- }
- c->cmd = strdup (argv[5]);
- c->next = CRON;
- CRON = c;
- }
- }
-
-
- static void
- processcrontab ()
- {
- struct crontab *c;
- time_t now;
- struct tm *tmp, t;
- char *cmd;
- #ifdef LOCK
- int lockedstate;
- #endif
-
- now = time ((time_t *)0);
- tmp = localtime (&now);
- /* Since calls from cmdparse CAN overwrite this temp
- buffer, we copy the time buffer locally */
- memcpy (&t, tmp, sizeof (struct tm));
- for (c = CRON; c; c = c->next) {
- if (!c->minute[t.tm_min])
- continue;
- if (!c->hour[t.tm_hour])
- continue;
- if (!c->day[t.tm_mday - 1])
- continue;
- if (!c->dayofweek[t.tm_wday])
- continue;
- if (!c->month[t.tm_mon])
- continue;
- cmd = _variable_expansion (strdup (c->cmd));
- #ifdef LOCK
- lockedstate = Kblocked;
- Kblocked = 0;
- #endif
- (void) cmdparse (Cmds, cmd, NULL);
- #ifdef LOCK
- Kblocked = lockedstate;
- #endif
- free (cmd);
- }
- }
-
-
- #endif /* CRONTAB */
-